package com.web.kdl.controller.send;

import cn.hutool.core.util.ObjectUtil;
import com.web.kdl.common.result.CommonResult;
import com.web.kdl.daoV2.matrix.MatrixDao;
import com.web.kdl.entity.flywheelDataAnalysis.FlywheelDataAnalysis;
import com.web.kdl.entity.matrix.Matrix;
import com.web.kdl.entity.site.Site;
import com.web.kdl.entity.sitewheel.SiteWheel;
import com.web.kdl.service.send.MqttService;
import com.web.kdl.service.send.SendService;
import com.web.kdl.service.site.SiteService;
import com.web.kdl.service.siteWheel.SiteWheelService;
import com.web.kdl.util.ModbusUtil;
import com.web.kdl.util.RedisKeyUtil;
import com.web.kdl.util.RedisUtils;
import com.web.kdl.util.TopicUtils;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
public class Send {

    private static final Logger log = LoggerFactory.getLogger(Send.class);
    @Autowired
    private MqttService mqttService;
    @Autowired
    private SiteWheelService siteWheelService;

    @Autowired
    private SiteService siteService;

    @Autowired
    private MatrixDao matrixDao;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SendService sendService;

    private volatile String activeMode = "modbusMqtt"; // 默认运行 modbusMqtt
//    private volatile String activeMode = "modbusTcp";

//    @PostMapping("/send")
//    @SneakyThrows
//    @ResponseBody
//    public String sendTest() {
//
//        String hexDataFly1  = "06 E4 00 00 00 06 01 03 9C 41 00 64";//向飞轮一发出的请求，要求设备端返回数据，0064-返回100个寄存器里面的内容  寄存器地址9C41-40001
//        mqttService.sendHexData(hexDataFly1);//发送消息
//        String hexDataFly12 = "06 E4 00 00 00 06 01 03 9C A5 00 50";//向飞轮一发出的请求，要求设备端返回数据，0050-读取剩余80个寄存器里的内容 寄存器地址9CA5-40101
//        mqttService.sendHexData(hexDataFly12);//发送消息
//        Thread.sleep(3000);
//        String hexDataFly2  = "06 E4 00 00 00 06 01 03 9D 09 00 65";//接收到飞轮二，101个寄存器里面的内容 40201
//        mqttService.sendHexData(hexDataFly2);//接收到飞轮二，101个寄存器里面的内容
//        String hexDataFly22 = "06 E4 00 00 00 06 01 03 9D 6D 00 51";//接收到飞轮二，剩余81个寄存器里的内容 40301
//        mqttService.sendHexData(hexDataFly22);//接收到飞轮二，剩余81个寄存器里的内容
//        Thread.sleep(3000);
//        String hexDataFly3  = "06 E4 00 00 00 06 01 03 9D D1 00 66";//接收到飞轮三，102个寄存器里面的内容 40401
//        mqttService.sendHexData(hexDataFly3);//接收到飞轮三，102个寄存器里面的内容
//        String hexDataFly32 = "06 E4 00 00 00 06 01 03 9E 35 00 52";//接收到飞轮三，剩余82个寄存器里的内容 40501
//        mqttService.sendHexData(hexDataFly32);//接收到飞轮三，剩余82个寄存器里的内容
//        Thread.sleep(3000);
//        String hexDataFly4  = "06 E4 00 00 00 06 01 03 9E 99 00 67";//接收到飞轮四，103个寄存器里面的内容 40601
//        mqttService.sendHexData(hexDataFly4);//接收到飞轮四，103个寄存器里面的内容
//        String hexDataFly42 = "06 E4 00 00 00 06 01 03 9E FD 00 53";//接收到飞轮四，剩余83个寄存器里的内容 40701
//        mqttService.sendHexData(hexDataFly42);//接收到飞轮四，剩余83个寄存器里的内容
//        Thread.sleep(3000);
//        String hexData2 = "06 E4 00 00 00 06 01 03 9F 61 00 62";//接收除四个飞轮以外的剩余总控信息,98个寄存器 40801
//        mqttService.sendHexData(hexData2);//总控的信息传入80801
//        return "Message sent!";
//    }

    public static String getCurrentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    @PostMapping("/send")
    @SneakyThrows
    @ResponseBody
    public String sendTest() {
        //获取当前时间，存入redis
        String redisTimeKey = RedisKeyUtil.getRedisTimeKey();
        String currentTime = getCurrentTime();
        redisUtils.set(redisTimeKey,currentTime);
        //获取所有阵列
        List<Matrix> allMatrix = matrixDao.selectList(null);

        // 异步下发每个矩阵
        // 等待所有异步任务完成
        allMatrix.forEach(matrix -> sendService.sendMatrix(matrix) );
        return "Message sent!";
    }
    @PostMapping("/modbusTcp")
    @SneakyThrows
    @ResponseBody
    public String modbusTcp() {
        //获取当前时间，存入redis
        String redisTimeKey = RedisKeyUtil.getRedisTimeKey();
        String currentTime = getCurrentTime();
        redisUtils.set(redisTimeKey,currentTime);
        //获取所有阵列
        List<Matrix> allMatrix = matrixDao.selectList(null);

        // 异步下发每个矩阵
        // 等待所有异步任务完成
        allMatrix.forEach(matrix -> sendService.getModBusMatrix(matrix) );
        return "Message sent!";
    }
    /**
     * 切换任务模式
     * 使用示例: POST /api/task?mode=TASK_A
     */
    @GetMapping("/switchTask")
    public String switchTask(@RequestParam String mode) {
        this.activeMode = mode;
        return "已切换到任务模式: " + mode;
    }


    public void execute() {
        switch (activeMode) {
            case "modbusMqtt":
                sendTest();
                log.info("执行任务 modbusMqtt");
                break;
            case "modbusTcp":
                modbusTcp();
                System.out.println("执行任务 modbusTcp");
                break;
        }
    }

    //控制飞轮开关机
    @PostMapping("/send/flywheel")
    @ResponseBody
    public CommonResult sendFlywheel(String  matrixName, Integer flywheelSerial, Integer status) {
        //status 0 关机 1开机
        Matrix matrix = matrixDao.selectByName(matrixName);
        String topic = matrix.getTopic();
        String str = ModbusUtil.buildWriteSingleRegister(1, flywheelSerial, 200*(flywheelSerial-1)+40007, status);
        mqttService.sendHexData(str,topic);
        return CommonResult.success();
    }

    /**
     * 获取 当前飞轮开关情况
     * @param matrixName
     * @param flywheelSerial
     * @return
     */
    @PostMapping("/getFlyWheelStatus")
    public CommonResult getFlyWheelStatus(String  matrixName, Integer flywheelSerial) {
        Matrix matrix = matrixDao.selectByName(matrixName);
        Integer flyWheelStatus = 0;
        String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), flywheelSerial);
        // 对应 matrix id 下的 flywheel i 飞轮数据
        List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
        for (FlywheelDataAnalysis dto : list) {
            switch (dto.getDeviceName()) {
                case "系统控制":
                    flyWheelStatus= (int) dto.getDataValue();
                    break;
            }
        }
        return CommonResult.success(flyWheelStatus);
    }
}